//
// Created by yunlang on 2021/12/7.
//

#include<stdexcept>
#include<cstring>
#include"hfmCodeBitSet.h"
using namespace std;
const unsigned int hfmCodeBitSet::DataBlockLengeh = 32;

hfmCodeBitSet::hfmCodeBitSet()
{
    len = 0;
    data = new unsigned char[DataBlockLengeh];
    memset(data,0,DataBlockLengeh);
}

hfmCodeBitSet::hfmCodeBitSet(const hfmCodeBitSet &other)
{
    data = new unsigned char[DataBlockLengeh];
    initFromOther(other);
}

unsigned int hfmCodeBitSet::getLength() const
{
    return  len;
}

bool hfmCodeBitSet::append(unsigned char flag)
{
    if(len >= DataBlockLengeh * 8)
    {
        throw runtime_error("hfmCodeBitSet::append error: hfmCodeBitSet overflow");
    }
    unsigned int byteOff = len / 8;
    unsigned int bitOff = len % 8;
    if(flag)
        data[byteOff] |= (1 << bitOff);
    else
        data[byteOff] &= (~(1 << bitOff));
    len++;
    return true;
}

bool hfmCodeBitSet::pop_back()
{
    if(len <= 0)
        return false;
    len--;
    return true;
}

hfmCodeBitSet::~hfmCodeBitSet() { delete[] data; }

bool hfmCodeBitSet::operator[](unsigned int pos) const
{
    if(pos >= len || pos < 0)
        return false;
    unsigned int byteOff = pos / 8;
    unsigned int bitOff = pos % 8;
    bool res = static_cast<bool>((data[byteOff] >> bitOff) & 1);
    return res;
}

unsigned char *hfmCodeBitSet::getData() const
{
    return data;
}

hfmCodeBitSet& hfmCodeBitSet::operator=(const hfmCodeBitSet &other)
{
    initFromOther(other);
    return *this;
}

void hfmCodeBitSet::initFromOther(const hfmCodeBitSet &other)
{
    len = other.len;
    memcpy(data,other.getData(),DataBlockLengeh);
}



